package com.cib.process.chat.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cib.process.bean.*;
import com.cib.process.chat.core.AbstractActionSeletor;
import com.cib.process.chat.core.AbstractChatVisitSelector;
import com.cib.process.chat.service.IvrService;
import com.cib.process.chat.service.ServiceResultParser;
import com.cib.process.mapper.ChatMapper;
import com.cib.process.ngd.NGDService;
import com.cib.process.util.LoggerHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class IvrServiceImpl implements IvrService {
    @Autowired
    private ChatMapper chatMapper;
    @Autowired 
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private AbstractChatVisitSelector busnoChatVisitSelector;
    @Autowired
    private NGDService ngdService;
    @Autowired
    private ServiceResultParser<NGDQueryResult> queryResultParser;
    @Autowired
    private ServiceResultParser<NGDStartResult> firstEachResultParser;

    @Autowired
    private List<AbstractActionSeletor> abstractActionSelector;

    @Override
    public ServiceResult commonChat(IvrRequestServer ivrRequestServer) {
        try {
            String sessionId = ivrRequestServer.getSessionId();
            String userId = ivrRequestServer.getUserId();
            String token = ivrRequestServer.getToken();
            String sryhbz = ivrRequestServer.getSryhbz();
            LoggerHelper.info(this.getClass(),"[sessionId:{}] [userId:{}] [request:{}]",sessionId,userId,ivrRequestServer.toString());
            if (StringUtils.isBlank(token)){
                return ServiceResult.buildFailedResult(IvrReturnCode.TOKEN_EMPTY_ERROR);
            }

            String botId=getBotId(token,sessionId);  //IVR,WBG
            if (StringUtils.isBlank(botId)){
                LoggerHelper.err(this.getClass(),"[sessionId:{}] [userId:{}] [查询不到{}渠道下的botId ]",sessionId,userId,token);
                return ServiceResult.buildFailedResult(IvrReturnCode.BOTID_EMPTY_ERROR);
            }
            LoggerHelper.info(this.getClass(),"[sessionId:{}] [userId:{}] [token:{}] [botId:{}]",sessionId,userId,token,botId);

            //根据渠道不同进行权限访问控制，根据token的不同渠道配置名单管理
            boolean visit=busnoChatVisitSelector.isVisit(token,userId);
            if (!visit){
                LoggerHelper.err(this.getClass(),"[sessionId:{}] [userId:{}]",sessionId,userId);
                return ServiceResult.buildFailedResult(IvrReturnCode.COMMON_CHAT_NO_AUTH);
            }

            String lastAction = ivrRequestServer.getLastAction();
            if (StringUtils.isBlank(lastAction)){
                LoggerHelper.err(this.getClass(),"[sessionId:{}] [userId:{}] lastAction empty",sessionId,userId);
                return ServiceResult.buildFailedResult(IvrReturnCode.PARAM_ACTION_EMPTY_ERROR);
            }

            //如果第一次接入是1000
            if (Actions.DEFAULE.getCode().equals(lastAction)){
                LoggerHelper.info(this.getClass(),"[sessionId:{}] [userId:{}] first access:{}",sessionId,userId,lastAction);
                //调用start接口
                NGDStartResult start=ngdService.start(sessionId,userId,botId,token);
                return firstEachResultParser.parseResult(start,sessionId,userId);

            }

            //非首次交互，调用对话接口
            QueryRequestParam queryRequestParam=new QueryRequestParam();
            queryRequestParam.setVad(ivrRequestServer.getVad());
            queryRequestParam.setSessionId(sessionId);
            Map<String,Object> context=new HashMap<>();
            context.put("userId",userId);
            if ("IVR".equals(token)){
                context.put("sryhbz",sryhbz);
            }
            context.put("token",token);
            context.put("isCvv2","");
            queryRequestParam.setContext(context);

            //通过指令选择器处理相应指令
            for(final AbstractActionSeletor abstractActionSeletor:this.abstractActionSelector){
                abstractActionSeletor.paramSelector(ivrRequestServer,queryRequestParam);
            }

            //得到CVV2的值
            String cvv2 = queryRequestParam.getQueryText();
            //首次是不会执行，需要redis已经缓存cvv2的值
            if (Actions.NUM_CHAR.getCode().equals(lastAction)&&"cvv2".equals(redisTemplate.opsForHash().get("cvv2","cvvType_"+queryRequestParam.getSessionId()))){
                if (3==String.valueOf(cvv2).length()){
                    //将cvv2存入到redis
                    redisTemplate.opsForValue().set("cvvCode_"+queryRequestParam.getSessionId(),String.valueOf(cvv2),3*60, TimeUnit.SECONDS);
                    queryRequestParam.setQueryText("000");
                }else{
                    //设置一个默认cvv2让ngd识别
                    queryRequestParam.setQueryText("0000");
                }

                //删除，因为每次要验证CVV2每次另行通知
                redisTemplate.opsForHash().delete("cvv2","cvvType_"+queryRequestParam.getSessionId());
            }



            NGDQueryResult query=ngdService.query(queryRequestParam,userId,botId,token);
            return queryResultParser.parseResult(query,sessionId,userId);

        }catch (Exception e){
            LoggerHelper.err(this.getClass(),"[sessionId:{}] [userId:{}] commonchat fail {}",ivrRequestServer.getSessionId(),ivrRequestServer.getUserId(),e);
            return ServiceResult.buildFailedResult(IvrReturnCode.COMMON_CHAR_REQUEST_ERROR);
        }

    }

    private String getBotId(String token, String sessionId) {
        List<ChatTokenBean> chatTokenBeans=null;
        String char_token_channel = redisTemplate.opsForValue().get("CHAR_TOKEN_CHANNEL");
        if (StringUtils.isBlank(char_token_channel)){
            //查数据库
            List<ChatTokenBean> tokenAll = chatMapper.findTokenAll();
            if (chatTokenBeans!=null&&chatTokenBeans.size()>0){
                String s = JSON.toJSONString(chatTokenBeans);
                redisTemplate.opsForValue().set("CHAR_TOKEN_CHANNEL",s);
            }
        }else{
            //redis中有数据，将json串转换为ChatTokenBean的list
            chatTokenBeans= JSONObject.parseArray(char_token_channel, ChatTokenBean.class);
        }

        String botId="";
        if (chatTokenBeans!=null&&chatTokenBeans.size()>0){
            //使用非lamda表达式
            for (ChatTokenBean chatTokenBean : chatTokenBeans) {
                String token1 = chatTokenBean.getToken();
                if (token1.equals(token)){
                    botId=token1;
                    return botId;
                }

            }
        }

        return "";
    }
}
